/**
 * @copyright Copyright (c) 2025 Cation. 保留所有权利.
 * @file timing_wheel.c
 * @brief 时间轮调度算法-源文件
 * @version 1.0.0
 * @author Lxh
 * @date 2025-07-27
 * @details 
 * @note 
 * @history
 */
#include "timing_wheel.h"

// 平台特定的时间函数
#if PLATFORM_WINDOWS
static uint32_t get_current_time_ms() {
    return GetTickCount();
}

static void sleep_ms(uint32_t ms) {
    Sleep(ms);
}
#elif PLATFORM_LINUX
static uint32_t get_current_time_ms() {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

static void sleep_ms(uint32_t ms) {
    usleep(ms * 1000);
}
#elif PLATFORM_EMBEDDED
// 嵌入式平台需要用户实现这些函数
extern uint32_t get_current_time_ms(void); // 实现示例在下方
extern void sleep_ms(uint32_t ms);
#endif

// 初始化时间轮
timing_wheel_t* timing_wheel_init(uint32_t tick_ms) {
    timing_wheel_t *tw = (timing_wheel_t*)malloc(sizeof(timing_wheel_t));
    if (!tw) return NULL;
    
    memset(tw->slots, 0, sizeof(tw->slots));
    tw->current_slot = 0;
    tw->tick_ms = tick_ms;
    tw->last_tick = get_current_time_ms();
    return tw;
}

// 添加定时器
void timing_wheel_add(timing_wheel_t *tw, uint32_t timeout_ms, 
                     void (*callback)(void*), void *arg) {
    if (timeout_ms <= 0 || !callback || !tw) return;
    
    // 计算轮数和槽位
    uint32_t ticks = (timeout_ms + tw->tick_ms - 1) / tw->tick_ms;
    uint32_t rotation = ticks / 8;  // 8个槽
    uint32_t slot = (tw->current_slot + ticks) % 8;
    
    // 创建定时器节点
    timer_node_t *node = (timer_node_t*)malloc(sizeof(timer_node_t));
    if (!node) return;
    
    node->callback = callback;
    node->arg = arg;
    node->rotation = rotation;
    node->slot = slot;
    
    // 添加到对应槽的链表头部
    node->next = tw->slots[slot];
    tw->slots[slot] = node;
}

// 执行时间轮的tick操作
void timing_wheel_tick(timing_wheel_t *tw) {
    if (!tw) return;
    
    // 移动指针到下一个槽位
    tw->current_slot = (tw->current_slot + 1) % 8;
    
    // 处理当前槽的所有定时器
    timer_node_t **cur = &tw->slots[tw->current_slot];
    while (*cur) {
        timer_node_t *node = *cur;
        
        if (node->rotation > 0) {
            // 不需要触发，减少轮数
            node->rotation--;
            cur = &node->next;
        } else {
            // 触发定时器
            if (node->callback) {
                node->callback(node->arg);
            }
            
            // 从链表中移除节点
            *cur = node->next;
            free(node);
        }
    }
}

// 更新时间轮（需在循环中调用）
void timing_wheel_update(timing_wheel_t *tw) {
    if (!tw) return;
    
    uint32_t current = get_current_time_ms();
    uint32_t elapsed = current - tw->last_tick;
    
    // 计算需要推进的tick数
    uint32_t ticks = elapsed / tw->tick_ms;
    
    for (uint32_t i = 0; i < ticks; i++) {
        timing_wheel_tick(tw);
    }
    
    // 更新最后tick时间
    if (ticks > 0) {
        tw->last_tick += ticks * tw->tick_ms;
    }
}

// 销毁时间轮
void timing_wheel_destroy(timing_wheel_t *tw) {
    if (!tw) return;
    
    // 释放所有定时器节点
    for (int i = 0; i < 8; i++) {
        timer_node_t *node = tw->slots[i];
        while (node) {
            timer_node_t *next = node->next;
            free(node);
            node = next;
        }
    }
    
    free(tw);
}
